/* eslint-disable max-len */
/* eslint-disable no-param-reassign */
import {
  DEVICE_TYPE
} from '@/utils/device'
import echartTable from '@/components/SelfComponents/EchartTable'
import tableEllipsis from '@/components/Ellipsis/TableEllipsis'
import FullParentDomWithDask from '@/components/LoadDataSpin/FullParentDomWithDask.vue'
import { mapState, mapMutations } from 'vuex'
import lodash from 'lodash'
import Drawer from '@/components/Drawer/drawer.js'
import { useRouter, useRoute } from 'vue-router'
import router from '../router'
import Vue from 'vue'



const mixin = {
  computed: {
    ...mapState({
      layoutMode: state => state.app.layout,
      navTheme: state => state.app.theme,
      primaryColor: state => state.app.color,
      colorWeak: state => state.app.weak,
      fixedHeader: state => state.app.fixedHeader,
      fixSiderbar: state => state.app.fixSiderbar,
      fixSidebar: state => state.app.fixSiderbar,
      contentWidth: state => state.app.contentWidth,
      autoHideHeader: state => state.app.autoHideHeader,
      sidebarOpened: state => state.app.sidebar
    })
  },
  methods: {
    isTopMenu () {
      return this.layoutMode === 'topmenu'
    },
    isSideMenu () {
      return !this.isTopMenu()
    }
  }
}

const mixinDevice = {
  computed: {
    ...mapState({
      device: state => state.app.device
    })
  },
  methods: {
    isMobile () {
      return this.device === DEVICE_TYPE.MOBILE
    },
    isDesktop () {
      return this.device === DEVICE_TYPE.DESKTOP
    },
    isTablet () {
      return this.device === DEVICE_TYPE.TABLET
    }
  }
}
// 有echart和表格的公用
const mixinEchartTable = {
  components: { tableEllipsis, echartTable },
  data () {
    return {
      echartShowStatus: 1, // 1 加载中 2 加载完成有数据 3 加载完成无数据或加载失败
      data: [],
      loading: false,
      total: 0
    }
  },
  mounted () {
    this.getData()
  },
  methods: {
    paginationChage (pagination, Response) {
      pagination.current = Response.pageNo || 1
      pagination.pageSize = Response.pageSize || 10
      pagination.total = Response.totalRow || 0
      //   查询当前页大于总页数
      if (pagination.current !== 1 && pagination.current > Response.totalPage) {
        pagination.current = Response.totalPage || 1
        this.getData()
      }
    }
  }
}
// 下滑加载表格数据
const mixinTableScroll = {
  data () {
    return {
      pageCount: 1, // 当前页码
      totalPage: 1, // 总共的页码
      totalData: 0, // 总条数
      loadData: [], // 表格数据
      scrollLoadding: false,
      unScorllHeight: 0,
      // 在mounted函数中是否需要立即调用函数
      isMountedCallGetTableList: true
    }
  },
  mounted () {
    const vm = this
    this.isMountedCallGetTableList && vm.getTableList()
    vm.$nextTick(() => {
      const scrollDiv = document.querySelector('.commonTableSty .ant-table-body')
      const getScrollTop = scrollDiv.scrollTop
      const getHeight = scrollDiv.clientHeight
      const getScrollHeight = scrollDiv.scrollHeight
      scrollDiv.addEventListener('scroll', () => {
        // 是否还有数据 是否到底部 是否加载中
        if ((vm.pageCount < vm.totalPage) && getScrollTop + getHeight === getScrollHeight && !vm.scrollLoadding) {
          vm.pageCount = vm.pageCount + 1
          vm.getTableList()
        }
      })
      vm.getTableScrollHeight()
      window.onresize = function () { // 监听屏幕的改变
        vm.getTableScrollHeight()
      }
    })
  },
  methods: {
    tableRefresh () {
      document.querySelector('.commonTableSty .ant-table-body').scrollTo(0, 0) // 滚动条置顶
      this.pageCount = 1
      this.getTableList(true)
    },
    getTableScrollHeight () {
      const vm = this
      const searchHeight = document.querySelector('.table-page-search-wrapper').offsetHeight + 20
      const tableFooterHeight = document.querySelector('.tableFooter').offsetHeight
      const pageFooterHeight = document.querySelector('.footer').offsetHeight + 48
      vm.unScorllHeight = 38 + 32 + searchHeight + 57 + tableFooterHeight + pageFooterHeight
    }
  }
}

// 下拉某元素滚动条加载数据
const mixinScrollLoadData = {
  data () {
    return {
      // 需要下拉滚动加载数据的dom元素
      scrollDom: null,
      // 需要下拉滚动加载数据的dom元素对应的ref名称,需要在使用的组件中赋值
      scrollDomRef: 'scrollWrapper',
      // 需要下拉滚动加载数据的dom元素是否是a-table
      scrollDomIsAntTable: true,
      // 需要下拉滚动加载数据的dom元素最高高度
      scrollDomMaxScrollHeight: 100,
      // 需要绑定scroll事件的dom元素,如果下拉滚动加载数据的dom元素不是a-table时则与_scrollDom是相同的
      bindScrollDom: null,
      // 需要下拉滚动加载数据的dom元素是a-table时才需要此属性(表头dom元素)
      tbHead: null,
      // 当前页码
      pageCount: 1,
      // 总共的页码
      totalPage: 1,
      // 总条数
      totalData: 0,
      // 每页显示行数
      pageSize: 10,
      // 下拉滚动条距底部多少时开始加载新的数据
      distance: 5,
      // 是否正在加载数据
      loadingPageData: false
    }
  },
  mounted () {
    this.getScrollHeight()
    this.bindEvent()
  },
  methods: {
    // 获取需要下拉滚动加载数据的dom元素最高高度
    getScrollHeight () {
      if (this.scrollDom === null) {
        this.scrollDom = this.$refs[this.scrollDomRef]
        if (typeof this.scrollDom.nodeType === 'undefined') {
          // 如果ref是绑定在组件上的时候
          this.scrollDom = this.scrollDom.$el
        }
        this.scrollDom.style.overflowY = 'auto'
      }
      if (this.scrollDomIsAntTable && this.tbHead === null) {
        this.tbHead = document.querySelector('.ant-table-thead')
      }
      let height = this.scrollDom.offsetHeight
      if (this.tbHead) {
        height -= this.tbHead.offsetHeight
      }
      this.scrollDomMaxScrollHeight = height
      console.log(height, 'height')
    },
    bindEvent () {
      const vm = this
      if (this.bindScrollDom === null) {
        this.bindScrollDom = this.scrollDomIsAntTable ? document.querySelector('.ant-table-body') : this.scrollDom
      }
      // eslint-disable-next-line consistent-return
      vm.bindScrollDom.addEventListener('scroll', function () {
        if (vm.loadingPageData) {
          return false
        }
        if (this.scrollHeight - this.scrollTop - vm.scrollDomMaxScrollHeight > vm.distance) {
          return false
        }
        vm.pageCount = vm.pageCount + 1
        if (vm.pageCount > vm.totalPage) {
          return false
        }
        vm.loadPageData().then(() => {
          this.scrollTo(0, vm.scrollDomMaxScrollHeight * (vm.pageCount - 1))
        })
      })
      window.addEventListener('resize', () => {
        vm.getScrollHeight()
      })
    },
    // 刷新数据或者搜索数据
    refreshData () {
      this.bindScrollDom.scrollTo(0, 0) // 滚动条置顶
      this.pageCount = 1
      this.loadPageData()
    }
  }
}

// 关于右侧抽屉框使用的逻辑
const minxinDrawerUse = {
  computed: {
    ...mapState({
      'drawerConfig': (state) => state.app.drawerConfig,
      'drawerCotentComp': (state) => state.app.drawerConfig.compName,
      'drawerMainOpened': (state) => state.app.drawerMainOpened
    })
  },
  components: { FullParentDomWithDask },
  methods: {
    // ...mapMutations(['setDrawerConfig', 'toggleDrawerMain', 'resetDrawerConfig']),
    setDrawerConfig(config, global = false) {
      if (!global) {
        // Drawer.reset(router.currentRoute.fullPath);
        Drawer.open(router.currentRoute.fullPath, config);
      } else {
        Vue.$store.commit('setDrawerConfig', config)
      }
    },
    toggleDrawerMain(visible, global = false) {
      if (!global) {
        Drawer.show(router.currentRoute.fullPath, visible)
      } else {
        Vue.$store.commit('toggleDrawerMain', visible)
      }
    },
    resetDrawerConfig(loadCom, global = false) {
      if (!global) {
        Drawer.reset(router.currentRoute.fullPath, loadCom)
      } else {
        Vue.$store.commit('resetDrawerConfig', loadCom)
      }
    },
    // 显示右侧抽屉框(组件,标题,底部按钮,宽度[large,medium默认的,small],vars组件需要的参数, 副标题)
    showRightDrawer(compName, title, footerButtons, width, vars = {}, subTitle) {
      this.showRightDrawerInner(compName, title, footerButtons, width, vars, subTitle, null, false, null)
    },
    /**
     * 显示抽屉，但不先reset，这样重复点击打开不会清空抽屉中的数据
     * @param compName
     * @param title
     * @param footerButtons
     * @param width
     * @param vars
     */
    showRightDrawerNoReset(compName, title, footerButtons, width, vars = {}) {
      //设置key，第一次进入时通过key触发reset，后续通过key 保持不reset
      this.showRightDrawerInner(compName, title, footerButtons, width, vars, null, null, false, 'noReset', false)
    },
    showRightDrawerInner (compName, title, footerButtons, width, vars = {}, subTitle, onClose, global = false, key, reset = true) {
      let handler = () => {
        const config = {
          showFooter : true,
        }
        if (compName) {
          config.compName = compName
        }
        if (title) {
          config.title = title
        }
        if (footerButtons) {
          config.footerButtons = footerButtons
        }else{
          config.footerButtons=[{
            key: '',
            title: 'close',
            type: 'info',
            name: 'cancelBtn',
            method: null,
            callback: null,
            loading: false,
            disabled: false
          }]
        }
        if (width) {
          config.width = width
        }
        if (vars) {
          config.vars = vars
          console.log(vars, 'vars')
        }
        if (subTitle) {
          config.subTitle = subTitle
        }
        if (onClose) {
          config.onClose = onClose
        }
        if (key) {
          config.key = key
        }
        config.vueInstance = this
        this.setDrawerConfig(config, global)
        this.toggleDrawerMain(true, global)
      }
      if (!global) {
        if (reset) {
          this.resetDrawerConfig(FullParentDomWithDask, global);
          setTimeout(handler);
        } else {
          handler();
        }
      } else {
        this.drawerConfig.compName && this.resetDrawerConfig(FullParentDomWithDask, global);
        setTimeout(handler)
      }
    },
    // 移除右侧抽屉框
    removeRightDrawer (global = false) {
      if (global) {
        this.resetDrawerConfig(null, global);
        this.toggleDrawerMain(false, global);
      } else {
        Drawer.close(router.currentRoute.fullPath)
      }
    },
    /**
     * 设置是否显示 footer
     * @param showFooter
     */
    setShowFooter(showFooter, global = false){
      if (!global) {
        Drawer.open(router.currentRoute.fullPath, {showFooter});
      }else{
        const config = this.$store.state.app.drawerConfig;
        config.showFooter = showFooter;
        this.setDrawerConfig(config, global)
      }
    },
    // 获取右侧抽屉框底部默认按钮(确定,与取消按钮),如果是特殊的不适合，需要自己自定义
    getRightDrawerFooterButtons (config = { key: '', method: 'saveData', callback: 'searchData' }) {
      const { key, method, callback } = config
      // key用于标识按钮身份，可用于检测是否有权限
      // method指定保存数据要执行的方法
      // callback 用于指定关闭弹框要执行的方法 
      console.log("getRightDrawerFooterButtons",this);
      console.log("getRightDrawerFooterButtons",this[method]);
      console.log("getRightDrawerFooterButtons",this[callback]);
      return [{
        key,
        title: 'sure',
        type: 'primary',
        name: 'saveDataBtn',
        method: typeof method === 'string' ? this[method] : method,
        callback: typeof callback === 'string' ? this[callback] : callback,
        loading: false,
        disabled: false
      }, {
        key: '',
        title: 'cancel',
        type: 'info',
        name: 'cancelBtn',
        method: null,
        callback: null,
        loading: false,
        disabled: false
      }]
    }
  },
  beforeDestroy () {
    if (!this.drawerCotentComp) {
      return
    }
    this.removeRightDrawer()
  }
}

// 获取容器大小（例如表格内容区域产生滚动条的时候就需要)
const minxinGetDomHeight = {
  data () {
    return {
      // 要获取高度的容器的父元素或者祖辈,需要使用处定义
      wrapRef: '',
      // 要减去的元素高度类名,需要使用处定义
      expectCls: '',
      // 可看区域最在高度
      contentHeight: ''
    }
  },
  methods: {
    getDomHeight () {
      this.contentHeight = 200;
      this.$nextTick(() => {
        this.reGetDomHeight();
      });
    },
    reGetDomHeight () {
      const wrap = this.$refs[this.wrapRef]
      if (!wrap) {
        this.contentHeight = ''
      }
      const tbHeader = document.querySelector(this.expectCls)
      if (!tbHeader) {
        this.contentHeight = wrap.offsetHeight
        return
      }
      this.contentHeight = wrap.offsetHeight - tbHeader.offsetHeight
    },
    bindEvent () {
      window.addEventListener('resize', this.getDomHeight)
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.getDomHeight()
    })
    this.bindEvent()
  },
  beforeDestroy () {
    window.removeEventListener('resize', this.getDomHeight)
  }
}
// 获取容器大小（例如表格内容区域产生滚动条的时候就需要)
const minxinGetDomHeight2 = {
  props: {
    wrapRef: {
      type: String,
      default: 'pageViewSty'
    },
    substractHeightRefs: {
      type: Array,
      default () {
        return ['tableListSearch', 'tableListAction', 'pagination-wrapper', 'ant-table-thead']
      }
    },
    substractSpaceRefs: {
      type: Array,
      default () {
        return ['tableListPage', 'tableListAction', 'tableListMain', 'pagination-wrapper', 'commonTableWrap']
      }
    },
    offsetHeight: {
      type: Number,
      default: 0
    }
  },
  data () {
    return {
      // 要获取高度的容器的父元素或者祖辈,需要使用处定义,类名
      // wrapRef: 'pageViewSty',
      // 待减去高度的组件列表,类名
      // substractHeightRefs: ['tableListPageTop', 'pagination-wrapper', 'ant-table-thead'],
      // 待减去空闲空间(margins/paddings)的组件列表,类名
      // substractSpaceRefs: ['tableListPage', 'pagination-wrapper', 'commonTableWrap'],
      // 偏移值，此值直接减去
      // offsetHeight: 0,
      // 最终计算可看区域高度结果
      contentHeight: ''
    }
  },
  methods: {
    // element可能是html元素也可能是组件
    getEl (cls) {
      const element = document.querySelector('.' + cls)
      return element
    },
    calcContentHeight () {
      console.log('calcContentHeight')
      const anchorEl = this.getEl(this.wrapRef)
      if (!anchorEl) {
        return
      }
      const maxHeight = anchorEl.offsetHeight
      // 计算需要减去高度的组件列表的总高度
      let substractHeight = 0
      this.substractHeightRefs.forEach((item) => {
        const el = this.getEl(item)
        if (el) {
          substractHeight += (el.offsetHeight ? el.offsetHeight : 0)
          console.log('item', item, el.offsetHeight, substractHeight)
        }
      })
      // 计算需要减去的空白区域 margins / paddings
      const anchorElSubstractSpaceHeight = this.calcSubtractSpace(anchorEl)
      let substractSpaceHeight = anchorElSubstractSpaceHeight || 0
      console.log('item0', maxHeight, substractSpaceHeight)
      this.substractSpaceRefs.forEach((item) => {
        substractSpaceHeight += this.calcSubtractSpace(this.getEl((item)))
        console.log('item2', item, this.calcSubtractSpace(this.getEl((item))), substractSpaceHeight)
      })
      this.contentHeight = maxHeight - substractHeight - substractSpaceHeight - this.offsetHeight
      console.log(this.contentHeight + 'contentHeight')
      console.log(this.wrapRef, this.substractHeightRefs, this.substractSpaceRefs, maxHeight, substractHeight, substractSpaceHeight, this.offsetHeight, '=========')
    },
    calcSubtractSpace (
      element,
      direction = 'all'
    ) {
      function numberPx (px) {
        return Number(px.replace(/[^\d]/g, ''))
      }
      let subtractHeight = 0
      if (element) {
        const ZERO_PX = '0px'
        const cssStyle = getComputedStyle(element)
        const marginTop = numberPx(cssStyle ? (cssStyle.marginTop || ZERO_PX) : ZERO_PX)
        const marginBottom = numberPx(cssStyle ? (cssStyle.marginBottom || ZERO_PX) : ZERO_PX)
        const paddingTop = numberPx(cssStyle ? (cssStyle.paddingTop || ZERO_PX) : ZERO_PX)
        const paddingBottom = numberPx(cssStyle ? (cssStyle.paddingBottom || ZERO_PX) : ZERO_PX)
        if (direction === 'all') {
          subtractHeight += marginTop
          subtractHeight += marginBottom
          subtractHeight += paddingTop
          subtractHeight += paddingBottom
        } else if (direction === 'top') {
          subtractHeight += marginTop
          subtractHeight += paddingTop
        } else {
          subtractHeight += marginBottom
          subtractHeight += paddingBottom
        }
      }
      return subtractHeight
    }
  }
}

const minxinWindowSizeEvent = {
  data () {
    return {
      wait: 100,
      // 需要改变窗口大小时要执行的方法名称
      resizeFuns: [],
      // 用于存储resize事件绑定的函数，便于移除
      handlerResizeFuns: []
    }
  },
  methods: {
    handler (fn) {
      return lodash.debounce(() => {
        typeof fn === 'function' && fn()
      }, this.wait)
    },
    start () {
      this.resizeFuns.forEach(fun => {
        if (!this[fun]) {
          return
        }
        const handler = this.handler(this[fun])
        this.handlerResizeFuns.push(handler)
        window.addEventListener('resize', handler)
      })
    },
    stop () {
      this.handlerResizeFuns.forEach(handler => {
        window.removeEventListener('resize', handler)
      })
    }
  },
  mounted () {
    this.start()
  },
  beforeDestroy () {
    this.stop()
  }
}
// 获取滚动条高度使锚点高亮
const minxinScrollTop = {
  data () {
    return {
      activeIndex: 0,
      activities: [
        {id: 'sw-step-1'},
        {id: 'sw-step-2'},
        {id: 'sw-step-3'},
        {id: 'sw-step-4'},
        {id: 'sw-step-5'},
        {id: 'sw-step-6'},
      ],
      scrollHeight: [],
    }
  },
  methods: {
    handleScroll(e){
      const sHeight=e.target.clientHeight + e.target.scrollTop
      if((Math.round(sHeight) === e.target.scrollHeight) || 
      (Math.round(sHeight)+1 === e.target.scrollHeight) ||
      (Math.round(sHeight)-1 === e.target.scrollHeight) ){
        this.activeIndex = this.scrollHeight.length -1
      }else if(e.target.scrollTop > this.scrollHeight[this.scrollHeight.length-1]-100){
          this.activeIndex = this.scrollHeight.length -1
      }else{
        this.scrollHeight.map((item,index)=>{
          if(e.target.scrollTop >= item){
            this.activeIndex = index;
          }
        })
      }
      // console.log('@@@@@@',e.target.scrollTop)
      // console.log('AAAAAAA',this.activeIndex)
    },
    getScrollHeight() {
      this.scrollHeight = []
      this.activities.map(item => {
          this.scrollHeight.push(document.getElementById(item.id).offsetTop - 10)
      })
      // console.log('@@@@@@@@',this.scrollHeight)
    },
  },
  mounted () {
    this.$nextTick(() => {
      this.getScrollHeight()
    })
  },
}
export {
  mixin,
  mixinDevice,
  mixinEchartTable,
  mixinTableScroll,
  mixinScrollLoadData,
  minxinDrawerUse,
  minxinGetDomHeight,
  minxinGetDomHeight2,
  minxinWindowSizeEvent,
  minxinScrollTop
}
